package com.maben.service.impl;

import com.alibaba.fastjson2.JSON;
import com.maben.domain.User;
import com.maben.repository.UserRepository;
import com.maben.service.UserService;
import com.maben.util.dto.UserDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户业务类实现
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;
    @PersistenceContext
    private EntityManager entityManager;

    /**
     * 测试原有API：通过id精准查询
     */
    @Override
    public Optional<User> findUserById(Long id) throws Exception {
        return userRepository.findById(id);
    }

    /**
     * 测试原有API：保存
     */
    @Override
    public User saveUser(User user) throws Exception {
        return userRepository.save(user);
    }

    /**
     * 测试自己写的API：根据单字段精准查询
     */
    @Override
    public List<User> findUserListByUsername(String username) throws Exception {
        return userRepository.findByUsername(username);
    }

    /**
     * 测试事物
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public void testTrans() throws Exception {
        User user1 = new User();
        user1.setUsername("admin001");
        user1.setNickName("测试001");
        user1 = this.saveUser(user1);
        System.out.println(JSON.toJSONString(user1));

        int i = 1 / 0;

        User user2 = new User();
        user2.setUsername("admin002");
        user2.setNickName("测试002");
        user2 = this.saveUser(user2);
        System.out.println(JSON.toJSONString(user2));
    }

    /**
     * 测试事物
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public void testTrans2() throws Exception {
        User user1 = new User();
        user1.setUsername("test001");
        user1.setNickName("测试001");
        user1 = this.saveUser(user1);
        System.out.println(JSON.toJSONString(user1));

        saveTestUser2();
    }


    private void saveTestUser2() throws Exception {
        User user2 = new User();
        user2.setUsername("test002");
        user2.setNickName("测试002");
        user2 = this.saveUser(user2);
        System.out.println(JSON.toJSONString(user2));

        int i = 1 / 0;
    }


    /**
     * 测试通用查询，带分页
     */
    @Override
    public Page<User> findList(UserDto userDto, Pageable pageable) throws Exception {
        final StringBuilder selectBuilder = new StringBuilder("select * ");
        //添加公共SQL
        final StringBuilder commonBuilder = new StringBuilder(" FROM sys_user WHERE 1=1");
        final Map<String, Object> params = new HashMap<>();
        if (userDto.getUsername() != null) {
            commonBuilder.append(" AND username like :username");
            params.put("username", "%" + userDto.getUsername() + "%");
        }
        selectBuilder.append(commonBuilder);
        // 添加排序逻辑
        if (pageable.getSort() != null && !pageable.getSort().isEmpty()) {
            selectBuilder.append(" ORDER BY ");
            selectBuilder.append(
                    pageable.getSort().stream()
                    .map(order -> {
                        String columnName = order.getProperty();
                        String direction = order.isAscending() ? "ASC" : "DESC";
                        return columnName + " " + direction;
                    })
                    .collect(Collectors.joining(", "))
            );
        }
        // 构建查询
        final Query query = entityManager.createNativeQuery(selectBuilder.toString(), User.class);
        //添加参数
        params.forEach(query::setParameter);
        // 设置分页
        query.setFirstResult((int) pageable.getOffset());
        query.setMaxResults(pageable.getPageSize());
        // 执行查询
        List<User> resultList = query.getResultList();

        // 计算总记录数
        final StringBuilder selectCountBuilder = new StringBuilder("select count(1) ");
        final Query countQuery = entityManager.createNativeQuery(selectCountBuilder.append(commonBuilder).toString());
        params.forEach(countQuery::setParameter);
        Long total = Long.parseLong(countQuery.getSingleResult().toString());
        return new PageImpl<>(resultList, pageable, total);
    }
}
